/*
 * Primitive.h
 * - Base abstract class for a geometric object
 * 
 *
 * @version 	1.00 May 2011
 * @author 		Eric Stock
 */

#ifndef __PrimitiveH
#define __PrimitiveH

#include "MathLib.h"
#include "Utility.h"
#include "Light.h"
#include "Tree.h"
#include "Material.h"
#include <math.h>
#include <iostream>
#include <string>
#include <stdio.h>


using namespace std;


class Primitive
{
public:
	
	enum eActualPrimitive
	{
		AP_Sphere,
		AP_Plane
	};
	
	Primitive(void) :
		m_Material()
	{};

	virtual bool IntersectRay(math::Vertex& p_vOrigin, math::Vector& p_vRay, math::Vertex& p_vIntersectPt, flt& p_fDist, int& p_iInside) = 0;
	virtual bool IntersectAABB(Tree::Box& p_Box) = 0;
	virtual Colour Shade(Light& p_Light, math::Vertex& p_vCollisionPt, math::Vector& p_vRay, math::Vector& p_vSurfaceNorm);
	virtual Colour GetAmbientColour(Colour& p_colAmbient, flt p_fColourCoeff);
	virtual math::Vector GetNormalAtIntersection(math::Vertex& p_vIntersectPt) = 0;
	virtual flt  GetMaxExtent(Tree::Axes eAxis) = 0;
	virtual flt  GetMinExtent(Tree::Axes eAxis) = 0;
	virtual eActualPrimitive GetPrimitiveType() { return m_eActualPrimitive; }

	Material			m_Material;
	eActualPrimitive	m_eActualPrimitive;
};

class Sphere2 : public Primitive
{
public:

	Sphere2(void) :
		Primitive(),
		m_vCenter(0.0f, 0.0f, 0.0f),
		m_fRadius(1.0f),
		m_fRadiusSquared(1.0f)
	{
		m_eActualPrimitive = AP_Sphere;	
	};
	
	bool IntersectRay(math::Vertex& p_vOrigin, math::Vector& p_vRay, math::Vertex& p_vIntersectPt, flt& p_fDist, int& p_iInside);
	bool IntersectAABB(Tree::Box& p_Box);
	virtual math::Vector GetNormalAtIntersection(math::Vertex& p_vIntersectPt);
	virtual flt  GetMaxExtent(Tree::Axes eAxis);
	virtual flt  GetMinExtent(Tree::Axes eAxis);

	math::Vertex	m_vCenter;						
	flt				m_fRadius;
	flt				m_fRadiusSquared;

};

class Plane2 : public Primitive
{
public:
    
	Plane2(void) :
		Primitive(),
		m_vNormal(0.0f, 1.0f, 0.0f),
		m_fD(0.0f)
	{
		m_eActualPrimitive = AP_Plane;
	};

	bool IntersectRay(math::Vertex& p_vOrigin, math::Vector& p_vRay, math::Vertex& p_vIntersectPt, flt& p_fDist, int& p_iInside);
	bool IntersectAABB(Tree::Box& p_Box);
	virtual math::Vector GetNormalAtIntersection(math::Vertex& p_vIntersectPt) { return m_vNormal; }
	virtual flt  GetMaxExtent(Tree::Axes eAxis);
	virtual flt  GetMinExtent(Tree::Axes eAxis);
	
	Vector		m_vNormal;
	flt			m_fD;
};


#endif 
